home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJSRC106.ARJ / EXPHDLR.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  22KB  |  867 lines

  1. /* This is file EXPHDLR.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:66,55 */
  17.  
  18. #include <process.h>
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <sys/stat.h>
  22. #include <time.h>
  23. #include <errno.h>
  24. #include <fcntl.h>
  25.  
  26. #include "build.h"
  27. #include "types.h"
  28. #include "gdt.h"
  29. #include "idt.h"
  30. #include "tss.h"
  31. #include "utils.h"
  32. #include "paging.h"
  33. #include "npx.h"
  34. #include "mono.h"
  35. #include "vcpi.h"
  36.  
  37. #define SEGFAULT(p) { \
  38.   printf("Segmentation violation in pointer 0x%08lx at %x:%lx\n", (p), tss_ptr->tss_cs, tss_ptr->tss_eip); \
  39.   return 1; \
  40.   }
  41.  
  42. extern word32 far *graphics_pt;
  43.  
  44. extern int was_user_int;
  45. extern word16 vcpi_installed;        /* VCPI Installed flag */
  46. static word16 master_pic = 0x08;    /* Default IRQ0 Vector */
  47. word16 new_pic;                /* current IRQ0 Vector */
  48. char transfer_buffer[4096];    /* must be near ptr for small model */
  49.  
  50. word32 user_dta;
  51. static struct REGPACK r;
  52. static int in_graphics_mode=0;
  53. static int ctrl_c_causes_break=1;
  54.  
  55. static word32 flmerge(word32 rf, word32 tf)
  56. {
  57.   return (rf & 0xcff) | (tf & 0xfffff300L);
  58. }
  59.  
  60. static set_controller(v)
  61. {
  62. /*  disable();  */
  63.   outportb(0x20, 0x11);
  64.   outportb(0x21, v);
  65.   outportb(0x21, 4);
  66.   outportb(0x21, 1);
  67. /*  enable();  */
  68. }
  69.  
  70. static char _save_vectors[32];
  71.  
  72. init_controllers()
  73. {
  74.   disable();
  75.   master_pic = 0x08;
  76.   if (vcpi_installed)
  77.     master_pic = vcpi_get_pic();
  78.   if (master_pic == 0x08)
  79.   {
  80.     if (vcpi_installed)
  81.       vcpi_set_pic(0x78);
  82.     set_controller(0x78);
  83.     movedata(0, 0x78*4, FP_SEG(_save_vectors), FP_OFF(_save_vectors), 0x08*4);
  84.     movedata(0, 0x08*4, 0, 0x78*4, 0x08*4);
  85.     new_pic = 0x78;
  86.   }
  87.   else
  88.     new_pic = master_pic;
  89.   enable();
  90. }
  91.  
  92. uninit_controllers()
  93. {
  94.   disable();
  95.   if (master_pic == 0x08)
  96.   {
  97.     if (vcpi_installed)
  98.       vcpi_set_pic(master_pic);
  99.     set_controller(master_pic);
  100.     movedata(FP_SEG(_save_vectors), FP_OFF(_save_vectors), 0, 0x78*4, 0x08*4);
  101.   }
  102.   enable();
  103. }
  104.  
  105. extern int ctrl_c_flag;
  106.  
  107. exception_handler()
  108. {
  109.   int i;
  110. #if TOPLINEINFO
  111.   char buf[20];
  112.   sprintf(buf, "0x%08lx", tss_ptr->tss_eip);
  113.   for (i=0; buf[i]; i++)
  114.     poke(screen_seg, i*2+80, buf[i] | 0x0600);
  115. #endif
  116.   i = tss_ptr->tss_irqn;
  117. /*  printf("i=%#02x, a0=%02x\n", i, inportb(0xa0)); */
  118.   if (((i>=0x70) && (i<0x78) && (i != 0x75)) ||
  119.       ((i >= new_pic) && (i<new_pic+8)))
  120.   {
  121.     if ((i>=0x70) && (i<0x78))
  122.       intr(i, &r);
  123.     else
  124.       intr(i-new_pic+8, &r);
  125.     if (ctrl_c_causes_break)
  126.       if (i == new_pic+1)
  127.       {
  128.         r.r_ax = 0x0100;
  129.         intr(0x16, &r);
  130.         if (!(r.r_flags & 0x40) && (r.r_ax == 0x2e03))
  131.         {
  132.           _AH = 0;
  133.           geninterrupt(0x16);
  134.           ctrl_c_flag = 1;
  135.         }
  136.       }
  137.     if (ctrl_c_flag)
  138.     {
  139.       ctrl_c_flag = 0;
  140.       if (ctrl_c_causes_break)
  141.         return 1;
  142.     }
  143.     return 0;
  144.   }
  145.   switch (i)
  146.   {
  147.     case 8:
  148.       printf("double fault!\n");
  149.       exit(1);
  150.     case 0:
  151.     case 1:
  152.     case 2:
  153.     case 3:
  154.     case 4:
  155.     case 5:
  156.     case 6:
  157.     case 9:
  158.     case 10:
  159.     case 11:
  160.     case 12:
  161.     case 13:
  162.     case 15:
  163.       return 1;
  164.     case 0x75:
  165.       return 1;
  166.     case 7:
  167.       printf("Fatal!  Application attempted to use not-present 80387!\n");
  168.       printf("Floating point opcode at virtual address 0x%08lx\n", tss_ptr->tss_eip);
  169.       return 1;
  170.     case 14:
  171.       return page_in();
  172.  
  173.     case 0x10:
  174.       return i_10();
  175.     case 0x11:
  176.     case 0x12:
  177.     case 0x14:
  178.     case 0x16:
  179.     case 0x17:
  180.     case 0x1a:
  181.       return generic_handler();
  182.     case 0x21:
  183.       return i_21();
  184.     case 0x33:
  185.       return i_33();
  186.     default:
  187.       return 1;
  188.   }
  189. }
  190.  
  191. #if DEBUGGER
  192. static char flset[] = "VMRF  NT    OFDNIETFMIZR  AC  PE  CY";
  193. static char floff[] = "              UPID  PLNZ      PO  NC";
  194. static char fluse[] = {1,1,0,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1};
  195.  
  196. tssprint(TSS *t)
  197. {
  198.   int i;
  199.   printf("eax=%08lx  ebx=%08lx  ecx=%08lx  edx=%08lx\n",
  200.     t->tss_eax, t->tss_ebx, t->tss_ecx, t->tss_edx);
  201.   printf("esi=%08lx  edi=%08lx  ebp=%08lx ",
  202.     t->tss_esi, t->tss_edi, t->tss_ebp);
  203.   for (i=0; i<18; i++)
  204.     if (fluse[i])
  205.       if (t->tss_eflags & (1<<(17-i)))
  206.         printf(" %2.2s", flset+i*2);
  207.       else
  208.         printf(" %2.2s", floff+i*2);
  209.   printf("\nds=%04x es=%04x fs=%04x gs=%04x ss:esp=%04x:%08lx cs=%04x\n",
  210.     t->tss_ds, t->tss_es, t->tss_fs, t->tss_gs, t->tss_ss, t->tss_esp, t->tss_cs);
  211. }
  212. #endif /* DEBUGGER */
  213.  
  214. int retrieve_string(word32 v, char *transfer_buffer, char tchar)
  215. {
  216.   int i;
  217.   char c;
  218.   for (i=0; i<4096; i++)
  219.   {
  220.     c = peek8(v);
  221.     v++;
  222.     transfer_buffer[i] = c;
  223.     if (c == tchar)
  224.       break;
  225.   }
  226.   return i+1; /* number of characters placed in buffer */
  227. }
  228.  
  229. static int old_text_mode = -1;
  230.  
  231. generic_handler()
  232. {
  233.   tss2reg(&r);
  234.   intr(tss_ptr->tss_irqn, &r);
  235.   reg2tss(&r);
  236.   return 0;
  237. }
  238.  
  239. i_10()
  240. {
  241. #ifdef NONEWDRIVER
  242.   if ((tss_ptr->tss_eax & 0xFF00) == 0xFF00)
  243.   {
  244. #else
  245.   switch(tss_ptr->tss_eax & 0xFF00) {
  246.     case 0xFE00:
  247.       graphics_inquiry();
  248.       return 0;
  249. #endif
  250.     case 0xFF00:
  251.       graphics_mode(tss_ptr->tss_eax & 0xff);
  252.       in_graphics_mode = (peekb(0x40, 0x49) > 7);
  253.       return 0;
  254.   }
  255.   tss2reg(&r);
  256.   intr(0x10, &r);
  257.   reg2tss(&r);
  258.   tss_ptr->tss_ebp = r.r_es * 16L + r.r_bp + 0xe0000000L;
  259.   return 0;
  260. }
  261.  
  262. #ifndef NOEVENTS
  263.  
  264. #define  FOR_GO32
  265. #include "eventque.h"
  266.  
  267. #define  MSDRAW_STACK  128              /* stack size for mouse callback */
  268.  
  269. static word32  mousedraw_func32;        /* 32-bit mouse cursor drawing function */
  270. static word32  mousedraw_contaddr;      /* jump to this address after mouse draw */
  271. static char    mousedraw_active;        /* set while drawing mouse cursor */
  272. EventQueue    *event_queue = NULL;      /* event queue */
  273.  
  274. static void mousedraw_hook(void)
  275. {
  276.   disable();
  277.   if(!mousedraw_active) {
  278.     mousedraw_active = 1;
  279.     mousedraw_contaddr = a_tss.tss_eip;
  280.     a_tss.tss_eip = mousedraw_func32;
  281.   }
  282.   enable();
  283. }
  284.  
  285. i_33()
  286. {
  287.   void (*msdrawfun)(void);
  288.   int  queuesize;
  289.  
  290.   if(tss_ptr->tss_eax == 0x00ff) {
  291.     if(event_queue != NULL) {
  292.       EventQueueDeInit();
  293.       event_queue = NULL;
  294.     }
  295.     if((queuesize = (int)tss_ptr->tss_ebx) > 0) {
  296.       mousedraw_func32 = tss_ptr->tss_ecx;
  297.       mousedraw_active = 0;
  298.       msdrawfun =
  299.         (mousedraw_func32 != 0L) ? mousedraw_hook : NULL;
  300.       event_queue =
  301.         EventQueueInit(queuesize,MSDRAW_STACK,msdrawfun,master_pic,new_pic);
  302.       if(event_queue != NULL) {
  303.         tss_ptr->tss_ebx =
  304.           (((word32)FP_SEG(event_queue)) << 4) +
  305.           ((word32)FP_OFF(event_queue)) +
  306.           0xe0000000L;
  307.         tss_ptr->tss_ecx =
  308.           (((word32)FP_SEG(&mousedraw_contaddr)) << 4) +
  309.           ((word32)FP_OFF(&mousedraw_contaddr)) +
  310.           0xe0000000L;
  311.         tss_ptr->tss_edx =
  312.           (((word32)FP_SEG(&mousedraw_active)) << 4) +
  313.           ((word32)FP_OFF(&mousedraw_active)) +
  314.           0xe0000000L;
  315.       }
  316.       else tss_ptr->tss_ebx = 0L;
  317.     }
  318.     tss_ptr->tss_eax = 0x0ff0;              /* acknowledge event handling */
  319.     return(0);
  320.   }
  321. #else  /* NOEVENTS */
  322. i_33()
  323. {
  324. #endif /* NOEVENTS */
  325.   if (*((unsigned far *)0x000000CEL) == 0)
  326.     return 0;
  327.   r.r_ax = tss_ptr->tss_eax;
  328.   r.r_bx = tss_ptr->tss_ebx;
  329.   r.r_cx = tss_ptr->tss_ecx;
  330.   r.r_dx = tss_ptr->tss_edx;
  331.   intr(0x33, &r);
  332.   tss_ptr->tss_eax = r.r_ax;
  333.   tss_ptr->tss_ebx = r.r_bx;
  334.   tss_ptr->tss_ecx = r.r_cx;
  335.   tss_ptr->tss_edx = r.r_dx;
  336.   return 0;
  337. }
  338.  
  339. TSS last_tss;
  340.  
  341. i_21()
  342. {
  343.   word32 v, trans_total, countleft;
  344.   int i, c, ah, tchar, trans_count;
  345.   char *cp;
  346.   memcpy(&last_tss, tss_ptr, sizeof(TSS));
  347.   tss2reg(&r);
  348.   ah = (tss_ptr->tss_eax >> 8) & 0xff;
  349. #if 0
  350.   printf("int 21h ax=0x%04x bx=0x%04x cx=0x%04x dx=0x%04x\n",
  351.     (int)(tss_ptr->tss_eax),
  352.     (int)(tss_ptr->tss_ebx),
  353.     (int)(tss_ptr->tss_ecx),
  354.     (int)(tss_ptr->tss_edx)
  355.     );
  356. #endif
  357.   switch (ah)
  358.   {
  359.     case 1:
  360.     case 2:
  361.     case 3:
  362.     case 4:
  363.     case 5:
  364.     case 6:
  365.     case 7:
  366.     case 8:
  367.     case 0x0b:
  368.     case 0x0e:
  369.     case 0x19:
  370.     case 0x2a:
  371.     case 0x2b:
  372.     case 0x2c:
  373.     case 0x2d:
  374.     case 0x42:
  375.     case 0x45:
  376.     case 0x46:
  377.     case 0x57:
  378.     case 0x68:
  379.       intr(0x21, &r);
  380.       reg2tss(&r);
  381.       return 0;
  382.     case 0x33: /* ^C checking */
  383.       if ((r.r_ax & 0xff) == 0x01)
  384.         ctrl_c_causes_break = r.r_dx & 0xff;
  385.       intr(0x21, &r);
  386.       reg2tss(&r);
  387.       return 0;
  388.     case 0x3e:
  389. #if DEBUGGER
  390.       if (r.r_bx <= 2)
  391.         return 0;
  392. #endif
  393.       if (r.r_bx == 1)
  394.         redir_1_mono = redir_1_2 = 0;
  395.       if (r.r_bx == 2)
  396.         redir_2_mono = redir_2_1 = 0;
  397.       intr(0x21, &r);
  398.       reg2tss(&r);
  399.       return 0;
  400.     case 9:
  401.     case 0x39:
  402.     case 0x3a:
  403.     case 0x3b:
  404.     case 0x41:
  405.     case 0x43:
  406.       if (ah == 9)
  407.         tchar = '$';
  408.       else
  409.         tchar = 0;
  410.       v = tss_ptr->tss_edx + ARENA;
  411.       if (!page_is_valid(v))
  412.       {
  413.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  414.         return 1;
  415.       }
  416.       retrieve_string(v, transfer_buffer, tchar);
  417.       r.r_dx = FP_OFF(transfer_buffer);
  418.       r.r_ds = _DS;
  419.       intr(0x21, &r);
  420.       reg2tss(&r);
  421.       return 0;
  422.     case 0x3c:
  423.       v = tss_ptr->tss_edx + ARENA;
  424.       if (!page_is_valid(v))
  425.       {
  426.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  427.         return 1;
  428.       }
  429.       retrieve_string(v, transfer_buffer, 0);
  430.       i = _creat(transfer_buffer, (int)(tss_ptr->tss_ecx));
  431.       if (i < 0)
  432.       {
  433.         tss_ptr->tss_eax = errno;
  434.         tss_ptr->tss_eflags |= 1;
  435.       }
  436.       else
  437.       {
  438.         tss_ptr->tss_eax = i;
  439.         tss_ptr->tss_eflags &= ~1;
  440.       }
  441.       return 0;
  442.     case 0x3d:
  443.       v = tss_ptr->tss_edx + ARENA;
  444.       if (!page_is_valid(v))
  445.       {
  446.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  447.         return 1;
  448.       }
  449.       retrieve_string(v, transfer_buffer, 0);
  450.       i = tss_ptr->tss_eax & 0xf0;
  451.       if (tss_ptr->tss_eax & O_WRONLY) i &= 1;
  452.       if (tss_ptr->tss_eax & O_RDWR) i &= 2;
  453.       i = _open(transfer_buffer, i);
  454.       if (i < 0)
  455.       {
  456.         tss_ptr->tss_eax = errno;
  457.         tss_ptr->tss_eflags |= 1;
  458.       }
  459.       else
  460.       {
  461.         tss_ptr->tss_eax = i;
  462.         tss_ptr->tss_eflags &= ~1;
  463.       }
  464.       return 0;
  465.     case 0x1a:
  466.       user_dta = tss_ptr->tss_edx;
  467.       setdta((char far *)transfer_buffer);
  468.       return 0;
  469.     case 0x2f:
  470.       tss_ptr->tss_ebx = user_dta;
  471.       return 0;
  472.     case 0x30:
  473.       intr(0x21, &r);
  474.       reg2tss(&r);
  475.       return 0;
  476.     case 0x56:
  477.       v = tss_ptr->tss_edx + ARENA;
  478.       if (!page_is_valid(v))
  479.       {
  480.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  481.         return 1;
  482.       }
  483.       i = retrieve_string(v, transfer_buffer, 0);
  484.       r.r_dx = FP_OFF(transfer_buffer);
  485.       r.r_ds = _DS;
  486.       v = tss_ptr->tss_edi + ARENA;
  487.       retrieve_string(v, transfer_buffer+i, 0);
  488.       r.r_di = FP_OFF(transfer_buffer)+i;
  489.       r.r_es = _DS;
  490.       intr(0x21, &r);
  491.       tss_ptr->tss_eax = r.r_ax;
  492.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  493.       return 0;
  494.     case 0x3f:
  495.       trans_total = 0;
  496.       countleft = tss_ptr->tss_ecx;
  497.       v = tss_ptr->tss_edx;
  498.       if (!page_is_valid(v+ARENA))
  499.       {
  500.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  501.         return 1;
  502.       }
  503.       while (countleft > 0)
  504.       {
  505.         trans_count = (countleft <= 4096) ? countleft : 4096;
  506.         i = read(r.r_bx, transfer_buffer, trans_count);
  507.         if (i < 0)
  508.         {
  509.           tss_ptr->tss_eflags |= 1; /* carry */
  510.           tss_ptr->tss_eax = _doserrno;
  511.           return 0;
  512.         }
  513.         memput(v+ARENA, transfer_buffer, i);
  514.         trans_total += i;
  515.         v += i;
  516.         countleft -= i;
  517.         if (isatty(r.r_bx) && (i<trans_count))
  518.           break; /* they're line buffered */
  519.         if (i == 0)
  520.           break;
  521.       }
  522.       tss_ptr->tss_eax = trans_total;
  523.       tss_ptr->tss_eflags &= ~1;
  524.       return 0;
  525.     case 0x40:
  526.       trans_total = 0;
  527.       countleft = tss_ptr->tss_ecx;
  528.       if (countleft == 0)
  529.       {
  530.         r.r_ax = 0x4000;
  531.         r.r_cx = 0;
  532.         intr(0x21,&r);
  533.         tss_ptr->tss_eax = 0;
  534.         tss_ptr->tss_eflags &= ~1;
  535.         return 0;
  536.       }
  537.       v = tss_ptr->tss_edx;
  538.       if (!page_is_valid(v+ARENA))
  539.         SEGFAULT(v);
  540.       r.r_dx = (int)transfer_buffer;
  541.       while (countleft > 0)
  542.       {
  543.         trans_count = (countleft <= 4096) ? countleft : 4096;
  544.         memget(v+ARENA, transfer_buffer, trans_count);
  545.         if ((r.r_bx == 1) && redir_1_mono)
  546.           i = mono_write(transfer_buffer, trans_count);
  547.         else if ((r.r_bx == 2) && redir_2_mono)
  548.           i = mono_write(transfer_buffer, trans_count);
  549.         else
  550.         {
  551.           int fd = r.r_bx;
  552.           if ((r.r_bx == 2) && redir_2_1)
  553.             fd = 1;
  554.           else if ((r.r_bx == 1) && redir_1_2)
  555.             fd = 2;
  556.           i = write(fd, transfer_buffer, trans_count);
  557.           if (in_graphics_mode && (fd < 3))
  558.           {
  559.             word32 far *p = graphics_pt;
  560.             for (c = 0; c < 256; c++)
  561.               *p++ &= ~PT_P;
  562.           }
  563.         }
  564.         if (i<0) /* carry */
  565.         {
  566.           tss_ptr->tss_eflags |= 1; /* carry */
  567.           tss_ptr->tss_eax = _doserrno;
  568.           return 0;
  569.         }
  570.         trans_total += i;
  571.         v += i;
  572.         countleft -= i;
  573.         if (i < trans_count)
  574.           break;
  575.       }
  576.       tss_ptr->tss_eax = trans_total;
  577.       tss_ptr->tss_eflags &= ~1;
  578.       return 0;
  579.     case 0x44:
  580.       return i_21_44();
  581.     case 0x4e:
  582.       if (!page_is_valid(user_dta+ARENA))
  583.         SEGFAULT(user_dta);
  584.       v = tss_ptr->tss_edx + ARENA;
  585.       if (!page_is_valid(v))
  586.         SEGFAULT(v);
  587.       retrieve_string(v, transfer_buffer+43, 0);
  588.       r.r_dx = FP_OFF(transfer_buffer+43);
  589.       r.r_ds = _DS;
  590.       intr(0x21, &r);
  591.       reg2tss(&r);
  592.       for (i=20; i>=0; i--)
  593.         transfer_buffer[i+28] = transfer_buffer[i+26];
  594.       transfer_buffer[32+13] = 0; /* asciiz termination */
  595.       memput(user_dta+ARENA, transfer_buffer, 48);
  596.       return 0;
  597.     case 0x4f:
  598.       if (!page_is_valid(user_dta+ARENA))
  599.         SEGFAULT(user_dta);
  600.       memget(user_dta+ARENA, transfer_buffer, 48);
  601.       for (i=0; i<=20; i++)
  602.         transfer_buffer[i+26] = transfer_buffer[i+28];
  603.       intr(0x21, &r);
  604.       reg2tss(&r);
  605.       for (i=20; i>=0; i--)
  606.         transfer_buffer[i+28] = transfer_buffer[i+26];
  607.       transfer_buffer[32+13] = 0; /* asciiz termination */
  608.       memput(user_dta+ARENA, transfer_buffer, 48);
  609.       return 0;
  610.     case 0x47:
  611.       getcurdir((int)(tss_ptr->tss_edx & 0xff), transfer_buffer);
  612.       for (cp=transfer_buffer; *cp; cp++)
  613.       {
  614.         if (*cp == '\\') *cp = '/';
  615.         *cp = tolower(*cp);
  616.       }
  617.       memput(tss_ptr->tss_esi+ARENA, transfer_buffer, strlen(transfer_buffer)+1);
  618.       tss_ptr->tss_eax = (unsigned)r.r_ax;
  619.       tss_ptr->tss_eflags &= ~1;
  620.       return 0;
  621.     case 0x4a:
  622.       if (tss_ptr->tss_eax & 0xff)
  623.         tss_ptr->tss_eax = paging_sbrk(tss_ptr->tss_ebx);
  624.       else
  625.         tss_ptr->tss_eax = paging_brk(tss_ptr->tss_ebx);
  626.       return 0;
  627.     case 0x4c:
  628. #if DEBUGGER
  629.       printf("Program exited normally, return code %d (0x%x)\n",
  630.              (int)(tss_ptr->tss_eax & 0xff), (int)(tss_ptr->tss_eax & 0xff));
  631.       return 1;
  632. #else
  633. #if 0
  634.       {
  635.         int i, ch;
  636.         FILE *f = fopen("con", "w");
  637.         fprintf(f, "zero: ");
  638.         for (i=0; i<20; i++)
  639.         {
  640.           ch = *(char *)i;
  641.           fprintf(f, "%02x ", ch);
  642.         }
  643.         fprintf(f, "\r\n");
  644.       }
  645. #endif
  646.       exit(tss_ptr->tss_eax & 0xff);
  647. #endif
  648.     case 0xff:
  649.       return turbo_assist();
  650.     default:
  651.       return 1;
  652.   }
  653. }
  654.  
  655. struct time32 {
  656.   word32 secs;
  657.   word32 usecs;
  658. };
  659.  
  660. struct tz32 {
  661.   word32 offset;
  662.   word32 dst;
  663. };
  664.  
  665. struct    stat32 {
  666.     short st_dev;
  667.     short st_ino;
  668.     short st_mode;
  669.     short st_nlink;
  670.     short st_uid;
  671.     short st_gid;
  672.     short st_rdev;
  673.     short st_align_for_word32;
  674.     long  st_size;
  675.     long  st_atime;
  676.     long  st_mtime;
  677.     long  st_ctime;
  678.     long  st_blksize;
  679. };
  680.  
  681. static int dev_count=1;
  682.  
  683. turbo_assist()
  684. {
  685.   word32 p1, p2, p3, r;
  686.   struct time32 time32;
  687.   struct tz32 tz32;
  688.   struct stat32 statbuf32;
  689.   struct stat statbuf;
  690.   int i;
  691.  
  692.   char buf[128];
  693.   p1 = tss_ptr->tss_ebx;
  694.   p2 = tss_ptr->tss_ecx;
  695.   p3 = tss_ptr->tss_edx;
  696.   switch (tss_ptr->tss_eax & 0xff)
  697.   {
  698.     case 1:
  699.       retrieve_string(p1+ARENA, buf, 0);
  700.       r = creat(buf, S_IREAD | S_IWRITE);
  701.       break;
  702.     case 2:
  703.       retrieve_string(p1+ARENA, buf, 0);
  704.       r = open(buf, (int)p2, S_IREAD | S_IWRITE);
  705.       break;
  706.     case 3:
  707.       memset(&statbuf, 0, sizeof(statbuf));
  708.       r = fstat((int)p1, &statbuf);
  709.       statbuf32.st_dev = dev_count++;
  710.       statbuf32.st_ino = statbuf.st_ino;
  711.       statbuf32.st_mode = statbuf.st_mode;
  712.       statbuf32.st_nlink = statbuf.st_nlink;
  713.       statbuf32.st_uid = statbuf.st_uid;
  714.       statbuf32.st_gid = statbuf.st_gid;
  715.       statbuf32.st_rdev = statbuf.st_rdev;
  716.       statbuf32.st_size = statbuf.st_size;
  717.       statbuf32.st_atime = statbuf.st_atime;
  718.       statbuf32.st_mtime = statbuf.st_mtime;
  719.       statbuf32.st_ctime = statbuf.st_ctime;
  720.       statbuf32.st_blksize = 512;
  721.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  722.       break;
  723.     case 4:
  724.       if (p2)
  725.       {
  726.         if (!page_is_valid(p2+ARENA))
  727.           SEGFAULT(p2);
  728.         tz32.offset = timezone;
  729.         tz32.dst = daylight;
  730.         memput(p2+ARENA, &tz32, sizeof(tz32));
  731.       }
  732.       if (p1)
  733.       {
  734.         if (!page_is_valid(p1+ARENA))
  735.           SEGFAULT(p1);
  736.         time(&(time32.secs));
  737.         _AH = 0x2c;
  738.         geninterrupt(0x21);
  739.         time32.usecs = _DL * 10000L;
  740.         memput(p1+ARENA, &time32, sizeof(time32));
  741.       }
  742.       r = 0;
  743.       break;
  744.     case 5:
  745.       if (p2)
  746.       {
  747.         if (!page_is_valid(p2+ARENA))
  748.           SEGFAULT(p2);
  749.         memget(p2+ARENA, &tz32, sizeof(tz32));
  750.         timezone = tz32.offset;
  751.         daylight = tz32.dst;
  752.       }
  753.       if (p1)
  754.       {
  755.         if (!page_is_valid(p1+ARENA))
  756.           SEGFAULT(p1);
  757.         memget(p1+ARENA, &time32, sizeof(time32));
  758.         stime(&(time32.secs));
  759.       }
  760.       r = 0;
  761.       break;
  762.     case 6:
  763.       memset(&statbuf, 0, sizeof(statbuf));
  764.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  765.       r = stat(transfer_buffer, &statbuf);
  766.       statbuf32.st_dev = dev_count++;
  767.       statbuf32.st_ino = statbuf.st_ino;
  768.       statbuf32.st_mode = statbuf.st_mode;
  769.       statbuf32.st_nlink = statbuf.st_nlink;
  770.       statbuf32.st_uid = statbuf.st_uid;
  771.       statbuf32.st_gid = statbuf.st_gid;
  772.       statbuf32.st_rdev = statbuf.st_rdev;
  773.       statbuf32.st_size = statbuf.st_size;
  774.       statbuf32.st_atime = statbuf.st_atime;
  775.       statbuf32.st_mtime = statbuf.st_mtime;
  776.       statbuf32.st_ctime = statbuf.st_ctime;
  777.       statbuf32.st_blksize = 512;
  778.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  779.       break;
  780.     case 7:
  781.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  782.       page_out_everything();
  783.       uninit_controllers();
  784.       sscanf(transfer_buffer, "%s%n", buf, &i);
  785.       if (strpbrk(transfer_buffer, "<>|") == NULL)
  786.         r = spawnlp(P_WAIT, buf, buf, transfer_buffer+i, 0);
  787.       else
  788.         r = -1;
  789.       if (r & 0x80000000L)
  790.         r = system(transfer_buffer);
  791.       init_controllers();
  792.       page_in_everything();
  793.       break;
  794.     case 8:
  795.       _BX=(int)p1;
  796.       _AX=0x4400;
  797.       geninterrupt(0x21);
  798.       i = _DX;
  799.       if (p2 & O_BINARY)
  800.         i |= 0x20;
  801.       else
  802.         i &= ~0x20;
  803.       _BX=(int)p1;
  804.       _DX = i;
  805.       _AX=0x4401;
  806.       geninterrupt(0x21);
  807.       r = setmode((int)p1, (int)p2);
  808.       break;
  809.     case 9:
  810.       retrieve_string(p1+ARENA, buf, 0);
  811.       r = chmod(buf, (int)p2);
  812.       break;
  813.     default:
  814.       return 1;
  815.   }
  816.   tss_ptr->tss_eflags &= ~1;
  817.   if (r == -1)
  818.   {
  819.     tss_ptr->tss_eflags |= 1;
  820.     tss_ptr->tss_eax = errno;
  821.     return 0;
  822.   }
  823.   tss_ptr->tss_eax = r;
  824.   return 0;
  825. }
  826.  
  827. i_21_44()
  828. {
  829.   switch (tss_ptr->tss_eax & 0xff)
  830.   {
  831.     case 0x00:
  832.     case 0x01:
  833.     case 0x06:
  834.     case 0x07:
  835.       intr(0x21, &r);
  836.       tss_ptr->tss_edx = r.r_dx;
  837.       tss_ptr->tss_eax = r.r_ax;
  838.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  839.       return 0;
  840.     default:
  841.       return 1;
  842.   }
  843. }
  844.  
  845. tss2reg(struct REGPACK *r)
  846. {
  847.   r->r_ax = tss_ptr->tss_eax;
  848.   r->r_bx = tss_ptr->tss_ebx;
  849.   r->r_cx = tss_ptr->tss_ecx;
  850.   r->r_dx = tss_ptr->tss_edx;
  851.   r->r_si = tss_ptr->tss_esi;
  852.   r->r_di = tss_ptr->tss_edi;
  853.   r->r_flags = tss_ptr->tss_eflags;
  854.   r->r_ds = r->r_es = _DS;
  855. }
  856.  
  857. reg2tss(struct REGPACK *r)
  858. {
  859.   tss_ptr->tss_eax = r->r_ax;
  860.   tss_ptr->tss_ebx = r->r_bx;
  861.   tss_ptr->tss_ecx = r->r_cx;
  862.   tss_ptr->tss_edx = r->r_dx;
  863.   tss_ptr->tss_esi = r->r_si;
  864.   tss_ptr->tss_edi = r->r_di;
  865.   tss_ptr->tss_eflags = flmerge(r->r_flags, tss_ptr->tss_eflags);
  866. }
  867.